/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package com.pearreview.application;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Action;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.plaf.basic.BasicMenuBarUI;

import com.pearreview.ui.PearMenuUI;

/**
 * 
 * @author Dimitrij Pankratz, Anton Musichin
 *
 */
public final class MenuBarAdapter implements Serializable {
	
	private static final long serialVersionUID = 1092430373528429311L;
	
	private JMenuBar menuBar;
	private JMenu fileMenu;
	private JMenu helpMenu;
	private JMenu viewMenu;
	private JMenu propertiesMenu;
	private MouseListener menuMouseListener;
	
	private List<JMenu> afterFile = new ArrayList<JMenu>();
	private List<JMenu> afterView = new ArrayList<JMenu>();
	private List<JMenu> afterProperties = new ArrayList<JMenu>();
	private List<JMenu> afterHelp = new ArrayList<JMenu>();
	
	private List<JMenuItem> fileItems = new ArrayList<JMenuItem>();
	private List<JMenuItem> helpItems = new ArrayList<JMenuItem>();
	private List<JMenuItem> viewItems = new ArrayList<JMenuItem>();
	private List<JMenuItem> propertiesItems = new ArrayList<JMenuItem>();
	private List<JMenuItem> fileHistoryItems;
	
	private Action exitAction;
	private Action fullScreenAction;
	private Action propertiesAction;
	private Action helpAction;
	private Action newTabAction;
	private Action closeTabAction;
	private Action aboutAction;
	private Action licenseAction;
	private Action updateAction;
	private Action exportAction;
	private Action importAction;
	
	public static final int AFTER_FILE_MENU = 1;
	public static final int AFTER_VIEW_MENU = 2;
	public static final int AFTER_PROPERTIES_MENU = 3;
	public static final int AFTER_HELP_MENU = 4;
	
	public MenuBarAdapter(Action exitAction, 
			Action fullScreenAction, 
			Action propertiesAction, 
			Action helpAction,
			Action newTabAction,
			Action closeTabAction,
			Action aboutAction,
			Action licenseAction,
			Action updateAction,
			Action exportAction,
			Action importAction) {
		
		this.exitAction = exitAction;
		this.fullScreenAction = fullScreenAction;
		this.propertiesAction = propertiesAction;
		this.helpAction = helpAction;
		this.newTabAction = newTabAction;
		this.closeTabAction = closeTabAction;
		this.aboutAction = aboutAction;
		this.licenseAction = licenseAction;
		this.updateAction = updateAction;
		this.exportAction = exportAction;
		this.importAction = importAction;
		
		menuBar = new JMenuBar();
		if (!System.getProperty("os.name").equals("Mac OS X")) {
			menuBar.setUI(new BasicMenuBarUI());
			menuBar.setBackground(new Color(0xd6, 0xd6, 0xd6));
		}
		
		createMouseLister();
		createFileMenu();
		createHelpMenu();
		createPropertiesMenu();
		createViewMenu();
	}
	
	private void createMouseLister() {
		menuMouseListener = new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent mouseEvent) {
				JMenu c = (JMenu) mouseEvent.getSource();
				c.getModel().setRollover(true);
			}
			@Override
			public void mouseExited(MouseEvent mouseEvent) {
				JMenu c = (JMenu) mouseEvent.getSource();
				c.getModel().setRollover(false);
			}
		};
	}
	
	private void createFileMenu() {
		
		fileMenu = new JMenu(Messages.getString("PearReview.menu.file"));
		fileMenu.setUI(new PearMenuUI());
		fileMenu.setFont(new Font("Tahoma", Font.PLAIN, 12));
		fileMenu.addMouseListener(menuMouseListener);
	}
	
	private void createHelpMenu() {
		
		helpMenu = new JMenu(Messages.getString("PearReview.menu.help"));
		helpMenu.setUI(new PearMenuUI());
		helpMenu.setFont(new Font("Tahoma", Font.PLAIN, 12));
		helpMenu.addMouseListener(menuMouseListener);
	}
	
	private void createViewMenu() {
		
		viewMenu = new JMenu(Messages.getString("PearReview.menu.view"));
		viewMenu.setUI(new PearMenuUI());
		viewMenu.setFont(new Font("Tahoma", Font.PLAIN, 12));
		viewMenu.addMouseListener(menuMouseListener);
	}
	
	private void createPropertiesMenu() {
		
		propertiesMenu = new JMenu(Messages
				.getString("PearReview.menu.properties"));
		propertiesMenu.setUI(new PearMenuUI());
		propertiesMenu.setFont(new Font("Tahoma", Font.PLAIN, 12));
		propertiesMenu.addMouseListener(menuMouseListener);
	}
	
	/**
	 * Adds a menu to the MenuBar at given position.
	 * The normal MenuBar has the following order:
	 * 1.FileMenu, 2.ViewMenu, 3.PropertiesMenu, 4.HelpMenu 
	 * 
	 * @param menu
	 * @param pos
	 */
	public void addTopMenu(JMenu menu, int pos) {
		menu.setUI(new PearMenuUI());
		menu.addMouseListener(menuMouseListener);
		
		switch (pos) {
		case MenuBarAdapter.AFTER_FILE_MENU:
			afterFile.add(menu);
			break;
			
		case MenuBarAdapter.AFTER_VIEW_MENU:
			afterView.add(menu);
			break;
			
		case MenuBarAdapter.AFTER_PROPERTIES_MENU:
			afterProperties.add(menu);
			break;
			
		case MenuBarAdapter.AFTER_HELP_MENU:
			afterHelp.add(menu);
			break;
			
		default:
			afterHelp.add(menu);
			break;
		}
		
		buildMenuBar();
	}
	
	public JMenuBar getMenuBar() {
		buildFileMenu();
		buildViewMenu();
		buildPropertiesMenu();
		buildHelpMenu();
		
		buildMenuBar();
		
		return menuBar;
	}
	
	public void addFileMenuItem(JMenuItem item) {
		fileItems.add(item);
	}
	
	public void addHelpMenuItem(JMenuItem item) {
		helpItems.add(item);
	}
	
	public void addPropertiesMenuItem(JMenuItem item) {
		propertiesItems.add(item);
	}
	
	public void addViewItem(JMenuItem item) {
		viewItems.add(item);
	}
	
	public void setFileHistoryMenuItems(List<JMenuItem> fileHistoryItems) {
		this.fileHistoryItems = fileHistoryItems;
		buildFileMenu();
	}

	private void buildMenuBar() {
		menuBar.removeAll();
		
		menuBar.add(fileMenu);
		for(JMenu menu: afterFile) {
			menuBar.add(menu);
		}
		
		menuBar.add(viewMenu);
		for(JMenu menu: afterView) {
			menuBar.add(menu);
		}
		
		menuBar.add(propertiesMenu);
		for(JMenu menu: afterProperties) {
			menuBar.add(menu);
		}
		
		menuBar.add(helpMenu);
		for(JMenu menu: afterHelp) {
			menuBar.add(menu);
		}
	}
	
	private void buildFileMenu() {
		fileMenu.removeAll();
		
		/* new tab */
		JMenuItem item = new JMenuItem(newTabAction);
		fileMenu.add(item);
		
		/* close tab */
		item = new JMenuItem(closeTabAction);
		fileMenu.add(item);
		
		for (JMenuItem cItem: fileItems) {
			if(cItem == null) {
				fileMenu.addSeparator();
			}
			else {
				fileMenu.add(cItem);
			}
		}
		
		/* export, import */
		fileMenu.addSeparator();
		item = new JMenuItem(importAction);
		fileMenu.add(item);
		item = new JMenuItem(exportAction);
		fileMenu.add(item);
		
		/* file history */
		if(fileHistoryItems != null && fileHistoryItems.size() > 0) {
			fileMenu.addSeparator();
			for(int i = 0 ; i < fileHistoryItems.size() ; i++) {
				item = fileHistoryItems.get(i);
				//item.setMnemonic(0x30 + i);
				fileMenu.add(item);
			}
		}
		
		fileMenu.addSeparator();
		item = new JMenuItem(exitAction);
		fileMenu.add(item);
	}
	
	private void buildViewMenu() {
		viewMenu.removeAll();
		
		JMenuItem item = new JCheckBoxMenuItem(fullScreenAction);
		viewMenu.add(item);
		
		for (JMenuItem cItem: viewItems) {
			if(cItem == null) {
				viewMenu.addSeparator();
			}
			else {
				viewMenu.add(cItem);
			}
		}
	}
	
	private void buildPropertiesMenu() {
		propertiesMenu.removeAll();
		
		JMenuItem item = new JMenuItem(propertiesAction);
		propertiesMenu.add(item);
		
		for (JMenuItem cItem: propertiesItems) {
			if(cItem == null)
				propertiesMenu.addSeparator();
			else
				propertiesMenu.add(cItem);
		}
	}
	
	private void buildHelpMenu() {
		helpMenu.removeAll();
		
		JMenuItem item = new JMenuItem(helpAction);
		helpMenu.add(item);
		
		item = new JMenuItem(licenseAction);
		helpMenu.add(item);
		
		for (JMenuItem cItem: helpItems) {
			if(cItem == null) {
				helpMenu.addSeparator();
			}
			else {
				helpMenu.add(cItem);
			}
		}
		
		helpMenu.addSeparator();
		item = new JMenuItem(updateAction);
		helpMenu.add(item);
		
		helpMenu.addSeparator();
		item = new JMenuItem(aboutAction);
		helpMenu.add(item);
	}
}